{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a2e47875-b4be-43d8-b788-acc76bf6aed3",
   "metadata": {},
   "source": [
    "# 使用预训练的模型做预测\n",
    "\n",
    "除了用测试集验证模型效果外，同时还查看模型中各层的权重、偏置，预测数据时候各神经元的激活值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "62739355-37a1-4109-b4d3-f8ec99572921",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "from torch import nn\n",
    "from torch.utils.data import DataLoader\n",
    "from torchvision import datasets\n",
    "from torchvision.transforms import ToTensor\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d44c1422-7056-4910-82b0-4a1797bc6752",
   "metadata": {},
   "source": [
    "载入训练数据和测试数据，用于预测和验证效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "e55baded-ec0c-4f87-b684-0a3112497093",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# Download training data from open datasets.\n",
    "training_data = datasets.MNIST(\n",
    "    root=\"data\",\n",
    "    train=True,\n",
    "    download=True,\n",
    "    transform=ToTensor(),\n",
    ")\n",
    "\n",
    "# Download test data from open datasets.\n",
    "test_data = datasets.MNIST(\n",
    "    root=\"data\",\n",
    "    train=False,\n",
    "    download=True,\n",
    "    transform=ToTensor(),\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "352201e0-e01c-4b97-bb72-fa491e099b83",
   "metadata": {},
   "source": [
    "## 载入预训练的模型 Loading Models\n",
    "The process for loading a model includes re-creating the model structure and loading the state dictionary into it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "53add412-7143-4e62-ae0d-6218975c3598",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Using cpu device\n",
      "NeuralNetwork(\n",
      "  (flatten): Flatten(start_dim=1, end_dim=-1)\n",
      "  (linear_relu_stack): Sequential(\n",
      "    (0): Linear(in_features=784, out_features=64, bias=True)\n",
      "    (1): ReLU()\n",
      "    (2): Linear(in_features=64, out_features=64, bias=True)\n",
      "    (3): ReLU()\n",
      "    (4): Linear(in_features=64, out_features=10, bias=True)\n",
      "  )\n",
      ")\n"
     ]
    }
   ],
   "source": [
    "# Get cpu, gpu or mps device for training.\n",
    "device = (\n",
    "    \"cuda\"\n",
    "    if torch.cuda.is_available()\n",
    "    else \"mps\"\n",
    "    if torch.backends.mps.is_available()\n",
    "    else \"cpu\"\n",
    ")\n",
    "print(f\"Using {device} device\")\n",
    "\n",
    "# Define model\n",
    "class NeuralNetwork(nn.Module):\n",
    "    def __init__(self):\n",
    "        super().__init__()\n",
    "        self.flatten = nn.Flatten()\n",
    "        self.linear_relu_stack = nn.Sequential(\n",
    "            nn.Linear(28*28, 64),\n",
    "            nn.ReLU(),\n",
    "            nn.Linear(64, 64),\n",
    "            nn.ReLU(),\n",
    "            nn.Linear(64, 10)\n",
    "        )\n",
    "\n",
    "    def forward(self, x):\n",
    "        x = self.flatten(x)\n",
    "        logits = self.linear_relu_stack(x)\n",
    "        return logits\n",
    "\n",
    "model = NeuralNetwork().to(device)\n",
    "model.load_state_dict(torch.load(\"model_predict.pth\"))\n",
    "print(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e0b81ffb-6198-47ac-a54d-582036d42b04",
   "metadata": {},
   "source": [
    "### 查看模型中各层的权重和偏置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "196b2b27-d98f-4b3e-a7ad-fcda3c2e14bb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "第一隐藏层权重： tensor([[-0.0195,  0.0220, -0.0221,  ..., -0.0306,  0.0055,  0.0120],\n",
      "        [-0.0280, -0.0122,  0.0229,  ..., -0.0307,  0.0062, -0.0096],\n",
      "        [-0.0044, -0.0342,  0.0217,  ..., -0.0033, -0.0328,  0.0178],\n",
      "        ...,\n",
      "        [ 0.0209, -0.0292,  0.0077,  ..., -0.0334,  0.0252,  0.0041],\n",
      "        [ 0.0046,  0.0154,  0.0139,  ...,  0.0330,  0.0071, -0.0024],\n",
      "        [-0.0209,  0.0154, -0.0035,  ..., -0.0239, -0.0010, -0.0057]])\n",
      "第一隐藏层偏置： tensor([ 0.0296,  0.0425,  0.0893,  0.0680,  0.0476, -0.0102, -0.0141,  0.0039,\n",
      "         0.1179, -0.0051, -0.0063,  0.1402,  0.0305,  0.0803, -0.1300, -0.0338,\n",
      "         0.0416,  0.0299, -0.0043,  0.0756,  0.0449,  0.0931, -0.0292,  0.1133,\n",
      "         0.0456,  0.0377, -0.0042,  0.0035,  0.0477,  0.0054, -0.0119, -0.0474,\n",
      "         0.1227,  0.1388, -0.0281,  0.0813,  0.0178,  0.0552,  0.0490,  0.0072,\n",
      "        -0.0164,  0.0316, -0.0669,  0.1000,  0.0881,  0.0919, -0.0064, -0.0218,\n",
      "         0.0813,  0.0588,  0.0158, -0.0199,  0.0130, -0.0466,  0.0100, -0.1247,\n",
      "         0.1114,  0.1044, -0.0122, -0.0034,  0.0785, -0.0152, -0.0402, -0.0415])\n",
      "第二隐藏层权重： tensor([[-0.0563, -0.0641, -0.0325,  ...,  0.0980,  0.1307, -0.0628],\n",
      "        [ 0.0474, -0.0067, -0.0182,  ...,  0.0804,  0.0941,  0.0752],\n",
      "        [ 0.1841,  0.1053, -0.0109,  ..., -0.0493, -0.1440, -0.0285],\n",
      "        ...,\n",
      "        [ 0.2437,  0.3966, -0.3448,  ..., -0.1102, -0.0115,  0.0628],\n",
      "        [-0.1370,  0.0867,  0.1750,  ...,  0.0465,  0.1278, -0.1213],\n",
      "        [ 0.0573, -0.0602, -0.1162,  ..., -0.0504, -0.0274,  0.1009]])\n",
      "第二隐藏层偏置： tensor([ 0.0613, -0.0556,  0.2170, -0.0331,  0.0087,  0.0038, -0.0242,  0.1194,\n",
      "        -0.1149,  0.0857,  0.2528, -0.0365, -0.1136,  0.2322, -0.1338,  0.0782,\n",
      "        -0.0475,  0.1012,  0.2293, -0.0125,  0.1650,  0.0996,  0.1835, -0.0772,\n",
      "        -0.0919, -0.0349, -0.0830,  0.1514,  0.1181, -0.0754,  0.0235,  0.1931,\n",
      "        -0.0602, -0.0858,  0.0199,  0.1739, -0.0891, -0.0564, -0.0505,  0.0408,\n",
      "        -0.0315,  0.2024, -0.1083,  0.1851,  0.1893, -0.0402,  0.1810,  0.1339,\n",
      "        -0.0885, -0.0338,  0.0215, -0.0398, -0.0293, -0.1736,  0.1572,  0.0027,\n",
      "         0.0381,  0.0937,  0.0077, -0.0526,  0.0223, -0.2086,  0.0360, -0.0940])\n",
      "输出层权重： tensor([[-3.2534e-03,  4.4505e-02, -1.4822e-01,  2.4159e-01, -1.2649e-01,\n",
      "         -2.6954e-02, -1.2039e-01,  2.4011e-01, -5.0230e-02,  4.4404e-01,\n",
      "         -1.7705e-01,  9.6470e-04, -4.4233e-02, -1.6926e-02, -1.5379e-01,\n",
      "          6.0385e-01, -1.8699e-01, -1.2985e-01, -2.3855e-01, -9.9534e-02,\n",
      "          1.7219e-01,  6.8281e-02,  2.4858e-01, -1.0956e-01, -2.5428e-01,\n",
      "         -1.2136e-01, -7.9913e-02, -8.0732e-02, -6.8158e-02,  8.3840e-02,\n",
      "          1.1004e-02, -2.2385e-01, -3.3946e-02, -2.3403e-02, -1.4913e-01,\n",
      "          1.8774e-01,  1.4440e-01, -1.5498e-01, -3.0777e-02, -5.3725e-01,\n",
      "         -1.9087e-01, -2.3805e-01,  8.8907e-02, -1.4613e-01, -4.6100e-01,\n",
      "         -1.0540e-02, -3.6497e-01, -3.3924e-01, -1.3423e-01, -1.1152e-01,\n",
      "          8.3122e-02,  4.0271e-02, -1.7198e-01,  3.0428e-01,  2.8901e-01,\n",
      "         -4.5310e-02,  1.0313e-01, -3.8627e-01,  3.7437e-02, -9.2067e-02,\n",
      "          1.7127e-02,  4.5757e-02,  3.2498e-01,  1.9280e-01],\n",
      "        [ 2.0171e-01, -6.3532e-02, -2.7162e-01, -3.2064e-01, -6.6036e-02,\n",
      "          4.4056e-02,  8.5121e-02, -3.7619e-01,  2.3227e-01, -8.1479e-02,\n",
      "          3.3319e-01,  6.3291e-02, -6.0949e-02, -3.2472e-01,  5.9351e-02,\n",
      "         -3.6042e-01, -3.5502e-02,  4.1703e-01,  1.8142e-01,  9.3860e-02,\n",
      "         -1.4318e-01, -3.2246e-01, -1.9541e-01, -2.7804e-02,  1.1065e-01,\n",
      "         -4.5328e-01, -9.8576e-02,  1.1114e-01, -1.3846e-01, -9.9673e-02,\n",
      "         -8.2081e-02, -1.2492e-01, -6.3587e-02, -4.6172e-02, -1.6278e-01,\n",
      "         -3.0023e-01, -2.2194e-01,  1.4163e-01,  2.6828e-01, -2.3857e-01,\n",
      "          2.9525e-01,  6.7499e-02, -2.0892e-01,  3.4872e-01,  4.1419e-01,\n",
      "         -1.0368e-01,  3.6993e-01,  1.8787e-01, -8.5072e-02,  2.2975e-01,\n",
      "         -1.1250e-01,  2.5252e-01, -2.3388e-01, -1.2828e-01, -2.4120e-01,\n",
      "          3.6731e-02,  1.6173e-01,  2.3248e-01,  1.0876e-01,  1.1014e-01,\n",
      "         -3.6151e-02, -3.0127e-01,  1.6899e-01, -6.7070e-03],\n",
      "        [ 3.8320e-01, -1.0321e-01,  2.8060e-01, -4.1505e-01, -2.5645e-01,\n",
      "          4.5169e-03, -4.6993e-02,  1.1033e-01,  3.6727e-01,  5.7644e-01,\n",
      "          3.6159e-01, -1.6587e-01,  5.8019e-02,  1.3508e-01,  8.3435e-02,\n",
      "          1.4098e-01,  2.8439e-01, -9.1504e-02, -2.7552e-02, -4.0286e-02,\n",
      "          3.0576e-02,  5.0453e-01, -3.4170e-01,  5.9626e-02,  1.8237e-01,\n",
      "          2.3294e-01, -9.3465e-02, -1.2417e-01, -3.5868e-01,  1.8332e-01,\n",
      "          2.0099e-02,  3.7433e-01,  2.5299e-01, -1.0416e-01,  9.4507e-02,\n",
      "          1.1438e-01,  3.3790e-02, -2.1978e-01, -2.2887e-01, -4.5903e-01,\n",
      "         -3.4145e-01,  2.1213e-01,  2.2357e-01, -2.3670e-01,  1.7929e-01,\n",
      "          7.4415e-02,  2.1814e-01, -7.1893e-03, -5.6927e-02,  2.1083e-01,\n",
      "          1.7630e-01, -3.8970e-01, -1.9292e-01,  1.4985e-01, -4.3684e-01,\n",
      "          3.7205e-02, -4.4985e-03,  1.1139e-01,  6.8341e-02,  2.6335e-02,\n",
      "         -7.9717e-02,  5.3038e-02, -1.7264e-02,  1.0311e-01],\n",
      "        [-3.3298e-02,  3.6847e-02,  1.2413e-01,  5.6815e-02,  2.1413e-01,\n",
      "         -8.0569e-02,  9.4141e-02, -2.1005e-01, -1.9460e-01, -1.9385e-01,\n",
      "          1.7768e-01, -7.4433e-03, -9.8034e-02, -2.5197e-01,  2.2168e-01,\n",
      "         -2.6661e-01,  6.5067e-01, -2.6710e-01,  2.7202e-01,  1.1038e-01,\n",
      "         -3.5876e-01,  4.0973e-01,  3.9825e-01,  5.7796e-02,  1.0287e-01,\n",
      "         -2.8792e-02,  3.0798e-02, -4.8476e-01,  1.6726e-01,  5.2262e-02,\n",
      "         -1.2328e-03,  2.4525e-01,  1.6591e-01,  1.1681e-02,  5.2996e-01,\n",
      "         -3.5220e-01, -2.0780e-01, -1.4655e-01, -9.0882e-02, -1.5820e-01,\n",
      "          3.8702e-02, -1.5174e-01, -1.3915e-01, -3.5281e-01,  9.7171e-02,\n",
      "          1.0420e-01, -2.5475e-01,  4.0237e-01, -7.3397e-05,  1.8596e-01,\n",
      "         -1.0872e-01, -2.2287e-02,  1.9498e-02,  3.3368e-01, -1.4127e-01,\n",
      "         -4.9131e-02, -7.1912e-02,  7.5584e-02, -1.1097e-01,  8.2389e-02,\n",
      "         -7.9110e-02, -5.4226e-02,  3.0383e-01,  9.5168e-02],\n",
      "        [-2.7174e-01, -6.0858e-02, -1.1668e-01,  1.4214e-01,  4.9544e-01,\n",
      "         -1.8088e-01, -6.4259e-02,  8.6089e-02, -5.5138e-02, -3.8636e-01,\n",
      "         -1.6012e-01, -2.8535e-01,  4.1197e-02,  4.2602e-01,  1.1938e-01,\n",
      "         -1.9848e-01, -9.9495e-02, -3.1655e-01,  1.8054e-01, -1.5455e-01,\n",
      "         -4.2432e-02, -9.9304e-02, -2.6316e-01, -4.2428e-02,  8.3318e-02,\n",
      "          2.9243e-01, -5.5171e-02,  2.5630e-01, -7.3522e-02,  5.5028e-02,\n",
      "          6.8864e-02,  4.6163e-02,  1.3852e-01,  1.1987e-01, -1.8589e-01,\n",
      "          4.1227e-01,  2.6068e-01, -4.3629e-02,  3.2813e-02,  3.7530e-01,\n",
      "         -5.5932e-02,  4.4997e-01, -9.6690e-02,  2.1775e-01, -2.9025e-01,\n",
      "          6.4579e-02, -1.0133e-01, -4.2879e-02,  2.3668e-02, -2.6720e-01,\n",
      "          8.9956e-02,  4.4819e-01, -1.2212e-01, -3.9132e-01,  3.3778e-01,\n",
      "         -9.1861e-02, -1.6772e-02, -3.0941e-01,  1.1886e-01,  1.6580e-02,\n",
      "         -1.7925e-01, -4.1634e-01, -4.4012e-01, -1.2461e-01],\n",
      "        [-2.1715e-01,  1.2612e-01, -3.6664e-01,  1.5954e-01, -8.6591e-02,\n",
      "          6.8688e-02, -3.8124e-02, -7.5023e-02, -3.2290e-01, -2.9748e-01,\n",
      "          3.0393e-01, -1.3169e-01, -1.0475e-01, -3.0851e-02, -5.7899e-01,\n",
      "          4.5265e-02,  1.6344e-01, -1.8032e-03,  1.6184e-01,  1.7447e-01,\n",
      "          3.5641e-01,  8.2133e-02,  5.2564e-01,  2.3814e-02, -1.4072e-01,\n",
      "         -1.5218e-01, -3.8827e-02,  2.2737e-01,  3.0797e-01,  6.1185e-02,\n",
      "          6.5692e-02,  4.1137e-02, -3.0609e-02, -6.0616e-02, -1.1429e-01,\n",
      "         -1.5159e-03, -3.5504e-01,  2.5456e-02,  2.2572e-01,  5.3370e-01,\n",
      "         -2.7497e-01,  4.1086e-03,  4.5417e-02,  3.4347e-01,  1.7628e-01,\n",
      "          7.8889e-02,  2.6389e-01, -2.5010e-01,  9.3335e-03,  8.0410e-02,\n",
      "          4.3514e-03, -5.4185e-01,  2.4519e-01, -2.2344e-01,  3.8413e-01,\n",
      "          3.2326e-01,  4.9847e-01,  1.7476e-02, -9.2366e-02, -1.7134e-02,\n",
      "          2.7122e-01, -3.3946e-01,  2.9873e-02, -2.9647e-01],\n",
      "        [ 6.0249e-02,  3.2855e-02,  5.2725e-02, -5.2597e-02, -1.2173e-01,\n",
      "         -6.2448e-02, -2.9586e-02,  5.7109e-01,  2.1707e-02, -3.9100e-02,\n",
      "         -1.8319e-01, -2.2985e-01,  7.5416e-02, -9.6401e-02,  8.1204e-02,\n",
      "         -2.8611e-01, -2.3584e-01,  4.3281e-01, -3.4452e-01, -1.5902e-02,\n",
      "         -1.8226e-01, -2.6503e-02, -3.4252e-01, -1.0255e-01, -3.0912e-01,\n",
      "          7.3996e-03,  2.9054e-02,  5.4371e-01, -7.7536e-03, -9.8615e-02,\n",
      "          2.9574e-02,  9.5454e-02,  7.9828e-03, -6.3567e-02, -2.7764e-01,\n",
      "          6.4536e-01,  1.6058e-01,  4.9164e-02,  6.1685e-03, -2.2573e-01,\n",
      "          2.8772e-01, -3.6104e-01, -3.1368e-01, -1.7835e-01, -4.9930e-01,\n",
      "         -3.7238e-02,  1.9227e-01, -8.6436e-02,  9.3179e-02, -2.4657e-01,\n",
      "         -3.6651e-02,  5.2397e-02, -3.5650e-02, -1.4690e-02,  1.2823e-01,\n",
      "         -1.3939e-01, -8.6983e-02,  2.8421e-01,  5.5515e-03, -9.3632e-02,\n",
      "          2.7255e-02, -3.7870e-01,  2.2368e-01, -1.3699e-01],\n",
      "        [ 9.6791e-02, -2.1330e-02,  6.0455e-01, -3.3274e-02, -2.6985e-01,\n",
      "          1.3725e-01,  3.3156e-02, -4.3107e-01,  2.7519e-01, -1.0872e-01,\n",
      "         -6.6034e-02,  4.3771e-01,  5.2302e-02,  3.6360e-01,  2.4051e-01,\n",
      "         -7.1833e-03, -1.9193e-02, -2.6637e-01, -1.3272e-01, -1.4235e-01,\n",
      "         -5.2381e-02, -1.8105e-03, -4.5024e-02, -3.3265e-02, -1.1282e-01,\n",
      "         -4.6341e-01, -9.9563e-02, -5.3478e-01,  6.9335e-02, -3.0484e-02,\n",
      "          1.1696e-01,  1.4089e-01, -2.4266e-02,  3.1204e-02,  1.8141e-01,\n",
      "          3.7548e-02,  3.7497e-01,  2.0594e-01,  2.2532e-02, -6.1480e-01,\n",
      "          1.9315e-01,  3.8511e-01,  2.3545e-01,  2.5432e-01,  4.5443e-01,\n",
      "          1.8848e-03, -4.9501e-03, -3.7095e-02,  5.5358e-02, -4.9929e-03,\n",
      "         -2.9617e-02, -1.5727e-01,  8.3810e-03, -1.6816e-01,  3.3996e-02,\n",
      "          1.8393e-01, -1.1376e-01,  1.8416e-01,  1.3123e-01, -6.6831e-02,\n",
      "          6.3870e-03,  2.6138e-01, -6.0686e-01,  6.7701e-02],\n",
      "        [ 8.8876e-02,  5.7941e-02, -3.5016e-01,  5.6710e-02, -3.1699e-02,\n",
      "         -2.1507e-02,  3.1147e-02, -2.0155e-01,  1.9689e-01, -2.9615e-02,\n",
      "         -2.0760e-01,  1.0260e-01, -1.1345e-01, -4.2585e-01,  5.8115e-02,\n",
      "          1.0710e-01, -1.6641e-01, -9.2973e-03, -2.0675e-01, -1.3524e-01,\n",
      "          1.6469e-01, -8.3255e-02, -1.0276e-01,  1.1316e-01,  1.3246e-01,\n",
      "          3.9875e-01, -9.6859e-02,  1.3079e-01, -5.3444e-01, -2.2976e-01,\n",
      "          4.5999e-02, -1.6478e-01, -2.6280e-01, -4.2939e-03, -1.9105e-01,\n",
      "         -2.0289e-01,  1.0972e-01,  9.6983e-02, -1.1824e-01,  7.1798e-01,\n",
      "          1.2519e-02, -1.2863e-02,  2.6970e-01, -3.6262e-01, -1.1144e-01,\n",
      "          2.1813e-02,  5.1548e-02, -2.3445e-01,  3.7384e-02, -4.1903e-02,\n",
      "          9.1773e-02,  1.5017e-01,  4.2428e-01,  1.4058e-01, -2.1198e-01,\n",
      "         -4.0034e-01, -3.9371e-01, -7.9639e-02,  8.5924e-02, -5.7498e-02,\n",
      "         -2.1454e-01,  4.0797e-01,  3.7963e-01,  1.7491e-01],\n",
      "        [-4.0443e-01,  6.2075e-02, -2.4405e-02, -7.3128e-02,  1.5121e-02,\n",
      "          2.8670e-01, -5.8839e-02,  3.8615e-02, -3.9365e-01, -1.1051e-01,\n",
      "         -3.5494e-01,  3.2904e-01,  5.7171e-02,  4.5948e-01, -1.8030e-01,\n",
      "         -2.1163e-01, -2.8878e-01, -5.1174e-02,  3.3773e-01,  1.6718e-01,\n",
      "          1.4922e-01, -3.8947e-01,  9.2142e-02,  3.8681e-02,  1.2134e-01,\n",
      "          4.3410e-01,  5.1291e-02,  2.7071e-01,  4.5115e-01, -2.6494e-02,\n",
      "          1.8779e-02, -2.3331e-01, -3.8408e-01, -1.0890e-01, -8.0748e-02,\n",
      "         -1.9154e-01, -1.3291e-01,  6.6808e-02,  1.6974e-01,  9.4202e-02,\n",
      "          1.2804e-01, -3.3656e-01,  3.3414e-02, -2.5138e-01,  4.3936e-02,\n",
      "         -1.3312e-02, -4.1785e-01,  1.2110e-01, -1.6208e-01, -1.7973e-01,\n",
      "          5.4233e-02,  3.3847e-01,  8.0048e-02, -1.6679e-01,  8.8433e-03,\n",
      "         -3.1725e-01, -1.8351e-01, -4.1031e-01,  1.3961e-02,  1.2478e-01,\n",
      "          2.6132e-01,  5.3243e-01, -2.6031e-01,  3.0358e-01]])\n",
      "输出层偏置： tensor([-0.1774,  0.0530,  0.0688, -0.0728,  0.0332,  0.2327, -0.0102,  0.2033,\n",
      "        -0.2708,  0.0733])\n"
     ]
    }
   ],
   "source": [
    "\n",
    "# 获取第一层隐藏的权重和偏置\n",
    "first_hidden_layer_weights = model.linear_relu_stack[0].weight.data\n",
    "first_hidden_layer_bias = model.linear_relu_stack[0].bias.data\n",
    "\n",
    "# 获取第二隐藏层（实际上是第二个线性层，因为ReLU不是参数层）的权重和偏置\n",
    "second_hidden_layer_weights = model.linear_relu_stack[2].weight.data\n",
    "second_hidden_layer_bias = model.linear_relu_stack[2].bias.data\n",
    "\n",
    "# 获取输出层的权重和偏置\n",
    "output_layer_weights = model.linear_relu_stack[4].weight.data\n",
    "output_layer_bias = model.linear_relu_stack[4].bias.data\n",
    "\n",
    "# 打印权重和偏置\n",
    "print(\"第一隐藏层权重：\", first_hidden_layer_weights)\n",
    "print(\"第一隐藏层偏置：\", first_hidden_layer_bias)\n",
    "\n",
    "print(\"第二隐藏层权重：\", second_hidden_layer_weights)\n",
    "print(\"第二隐藏层偏置：\", second_hidden_layer_bias)\n",
    "\n",
    "print(\"输出层权重：\", output_layer_weights)\n",
    "print(\"输出层偏置：\", output_layer_bias)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "583ff4c8-a377-452c-9c76-a5d357383319",
   "metadata": {},
   "source": [
    "## 模型现在可以用来做预测，载入测试集中，随选 3*5 个样本，观察一下预测值和实际值是否相符。 \n",
    "\n",
    "This model can now be used to make predictions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "309c7455-99b6-4264-b917-45060cc81597",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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Z88Wp9MppUuXlvDwcNm+fbvMnTtX4uPj5cYbb5SRI0dKuXLlCvMloAij/uBL1B98jRqEL1F/9uDXt749c+aM9O7dWyIiIuTMmTOSlZWV+88cDoekp6dL7dq15aOPPpISJUrI2rVrpUyZMuJ0OqVy5crSrFkzS9e3YsUKWb9+vUREREhISIgMHTrU0udD4bJz/V28eFHmzZsnFSpUkNTUVDl8+LC8+uqrUqJECcueE4XLzvWXlZUlr732mkRFRUl2drakpKTImDFjuIe/n7FzDWZkZMgrr7witWvXltTUVAkKCpIhQ4ZY9nwofNSffZT09QKsNG/ePJk4caKUL19eKleuLJUrV5affvpJgoKC5KabbpI333xThgwZkvsXrJycHHE4HHL48GG56667ROTyoSUnTpyQAwcOSFxcnMTFxUlmZqaMHTtWKleu7PHajh8/LtOmTZPNmzeLw+GQ/v37y5YtW6R58+Zeee3wPTvX39y5c6VGjRrSq1cvERGZMGGCLFu2TB566KGCv3DYgp3rb/bs2dKuXTtp166diIjMnz9fli1bJn369Cn4C4dt2LkGp0yZIu3bt5fOnTuLiMjTTz8t27Ztk5tvvrngLxy2QP3Zh183G6GhodK2bVu5dOmSTJo0STp27CipqamSmJgoDRs2lF69eknp0qVz5xuGIQEBAdKxY0dZsmSJREdHy+effy7R0dGydu1amT59uvTt21dKliz4H1tMTIx0794997/kde3aVRYsWECz4UfsXH9paWmyY8eO3GYjMjJSEhMTC3xd2Ied6y8pKUlOnjyZO65atSr154fsXIOxsbEyYcKE3HH79u3l/fff99u/7BVH1J+NGMXApk2bDMMwjFOnThlTp041Tpw44XJebGyssXnzZsMwDGPcuHGGYRhGRkaGYRiGMXr0aK+u6aGHHjI+/fTT3PG2bduM1q1be/U5YA92rL+8unfvbuzdu9fS54Bv2LH+Dhw4YNSrV8944403jEOHDhnDhw83nE6nV58D9mHHGmzWrJmRkpKSO16yZIlx3333efU5YA/Un+/5/QZxkctfjY0YMUIiIiLk6NGjV/3qyzAM2bt3r+zYsSP3t33jx48Xkct3MkhJSZFVq1apxyUkJEh4eLjMnTvX7TUlJydLaGho7jg4OFiSk5Ov5WWhiLBj/f2vjz/+WHr06CH169f36PGw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",
      "text/plain": [
       "<Figure size 1000x700 with 15 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "model.eval()\n",
    "\n",
    "with torch.no_grad():\n",
    "    fig, ax = plt.subplots(3, 5, figsize=(10, 7))  # 创建一个3行5列的画布\n",
    "    for i, axi in enumerate(ax.flat):\n",
    "        t = int(torch.randint(low=0, high=10000, size=(1, 1))[0][0])  # 生成随机整数t作为测试集的下标，可随机选取测试集中的图片\n",
    "        x, y = test_data[t][0], test_data[t][1]\n",
    "        x = x.to(device)\n",
    "        pred = model(x)\n",
    "        pred = model(x)\n",
    "        predicted, actual = pred[0].argmax(0), y\n",
    "        axi.imshow(x.reshape(28, 28), cmap=\"bone\")  # 绘制图像\n",
    "        axi.set(xticks=[], yticks=[])\n",
    "        axi.set_xlabel(f\"实际：{actual}\\n预测：{predicted}\")\n",
    "    plt.rcParams[\"font.sans-serif\"] = \"FangSong\"\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e2607ad1-c8eb-4695-b165-58df7a3903bd",
   "metadata": {},
   "source": [
    "用数据集中的第一个样本预测一下，看看预测后，各层各神经元的激活值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "ff1d812d-8253-4fee-b6cc-3f5dc4b7f3c7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "预测值: \"7\", 实际值: \"7\"\n"
     ]
    }
   ],
   "source": [
    "x, y = test_data[0][0], test_data[0][1]\n",
    "with torch.no_grad():\n",
    "    x = x.to(device)\n",
    "    pred = model(x)\n",
    "    predicted, actual = pred[0].argmax(0), y\n",
    "    print(f'预测值: \"{predicted}\", 实际值: \"{actual}\"')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "69befb48-7058-404b-8d37-e6f29decbfc5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "第0层的激活值:\n",
      "[ 0.46497762  1.8669338  -0.9129058   1.2389984   2.2626479   0.07512591\n",
      " -0.38309968  0.54399186  1.4423015   0.536261    1.9764924   1.5057961\n",
      "  0.23844558  0.38114756  0.40221643  0.46987668  0.27146715  1.274637\n",
      " -0.49883738  0.24865481  0.79552007  1.075719    0.7903518   1.2697514\n",
      "  1.852175   -1.1983551  -0.16103308  1.8612244   0.05633884  0.5130293\n",
      "  1.3756769   2.2858562   1.0699114   1.1052482   0.5681926   0.7645401\n",
      " -0.39304185 -0.6281291   0.8571925   1.2891697   0.22259882 -0.06213266\n",
      "  1.3097606   0.4480669   1.6160623   0.85603905  2.4784517   1.2688293\n",
      "  1.36515     0.3124885   1.6299437  -0.1479131   0.8402942   0.8894825\n",
      "  2.7024019   1.1377822  -0.46651977  0.8129088   0.43705362 -0.15855323\n",
      "  1.9431658  -0.24175374  0.06677328  0.03472799]\n",
      "第1层的激活值:\n",
      "[ 0.48188904 -1.0580878   3.2078369   2.501559    0.49949443  0.8256546\n",
      " -0.43552938 -1.1672809   0.11953129  2.1901674   1.0923786   3.5640512\n",
      " -0.8554372   1.7905514   1.5281311   3.458475    0.941286   -1.0150945\n",
      "  1.8858632  -0.25153688  1.1031982   2.232267    3.8299809  -0.3758601\n",
      "  1.4895217   0.6212081  -1.2349597  -2.008957    1.5738604   0.01556862\n",
      " -0.8178652  -0.6000197  -0.928039   -0.38120666  2.8808067  -0.16733965\n",
      "  2.5220704   1.1508791  -0.23738976  0.1319632   0.75648177  3.0055974\n",
      "  2.9861972   0.90724164  3.9145277  -0.6313552  -1.418997    1.6966313\n",
      "  0.55710846  1.3501097  -0.21065494 -0.23896389  2.5194836   1.7318821\n",
      "  1.7161682   1.4969379   0.24422005 -0.00675168  0.17934725 -1.5237654\n",
      "  0.5739541   4.1640496   1.1814394   1.136941  ]\n",
      "第2层的激活值:\n",
      "[  0.28270984  -5.242114     3.0610437    4.1804614   -5.8833737\n",
      "   0.4093417  -11.402834     9.624073    -0.79080784   1.6843071 ]\n"
     ]
    }
   ],
   "source": [
    "activation_values = []\n",
    "# 定义一个函数来获取并存储 激活值\n",
    "def get_activations(model, x):\n",
    "    for name, module in model.named_modules():\n",
    "        # print(f\"name: {name}, module: {module}\")\n",
    "        if isinstance(module, nn.Linear):  # 若模块是线性层（全连接层）\n",
    "            x = module(x)\n",
    "            activation_values.append(x.detach().numpy())  # 存储激活值\n",
    "            x = torch.relu(x)  # 假设使用ReLU激活函数\n",
    "# 调用函数进行前向传播并收集激活值\n",
    "get_activations(model, x.reshape(-1))\n",
    "\n",
    "# 输出隐藏层的激活值\n",
    "for i, activation in enumerate(activation_values):\n",
    "    print(f\"第{i}层的激活值:\")\n",
    "    print(activation)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bde18261-acf6-44da-8971-b0b117ac66ab",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
